Game statistics#

Try me#

Open In ColabBinder

Problem definition#

You would like to build a program to collect statistics for a basketball game. The objective is to build a chatbot like assistant with the following logic and functionality: - Ask the user what is the name of the event - Ask the user the name of one of the teams - Ask the user for the name of the second team - Ask the user to confirm the start of the game - Once the name has started, ask the user if he wants to register a game statistic, either a fault or game points, or if he wants to stop the game: - if the user wants to register a fault, ask the user the number of the player and team that made the fault, and the number of the player that received the fault. Show a message with the total number of faults made by the player. - if the user wants to register points, ask the user for the player number and the team that score the points and if it´s a 1 point, 2 point or a 3 point shot. Show a message with the total number of points socred by the player.

It is very important to register the date and time of every statistic, including the game start. To store this type of information, you can use the datetime Python library, which provides convenient data types to deal with time and dates. Specifically, you can use: - datetime.datetime.now(): This functions returns a datetime object with the current date and time. - isoformat(): this datetime object method returns a string with the date and time in ISO standard format

Also, you may use a Python dictionaries to store the information of the statistics. This way, you can initialise the stats registry as an array:

stats_array = []

And then, use the information provided by the user to build different dictionaries to store the information required for each type of statistic. The key type can be used to identify the type of statistic. The following code snippet contain examples for each type of statistic:

# Game start
{'type': 'game_start', 'timestamp': '2022-01-05T11:42:03.792167', 'teams': ['Valencia Basket', 'Real Madrid']}

# Shot
{'type': 'shot', 'timestamp': '2022-01-05T11:43:17.030771', 'player': 7, 'points': 3, 'team': 0}

# Fault
{'type': 'fault', 'timestamp': '2022-01-05T11:43:45.966949', 'player': 6, 'team': 1, 'received_by': 11}]

Design the flow diagram for the main chatbot and the functions required to show the statistics of each player and build a Python program to implement this chatbot

Solution#

Flow diagram#

In this solution, as suggested in the problem description, we are going to define an array to store the different statistics, collecting the required information from the user when needed. We are going to use two two functions to iterate on the stats array and calculate on the fly the total number of points or the number of faults of the player, so that we can output this information to the user interface.

The following flow diagram illustrates the diagram flow of the function that calculates the number of points of a player.

game statistic points

Basically, the function has two input parameters, the player, and the team. Using this data, we iterate over the array and add the points whenever there is a statistic of type point for that player of that team.

Similarly, the following diagram illustrates the logic of the function that calculates the total faults of a player.

game statitisc faults

Finally, our application is basically a bot that prompts messages in the user interface to get the required data from the user, and appends the statistics to the array, until the user enters the keyword “stop” when he/she is prompted for the type of statistic:

game statistics

First, our program asks for the name of the game, and the names of the two teams, and for the confirmation of the game start. Once the game starts, the program initialises the stats_array and starts a while loop where it asks the user for the type of statistic to enter, either fault, shot, or stop to finalise the game. If the user enters fault, the program asks for the number of the player and the team that made the fault, adds these data to the statistic, and calls the function get_points to show the total number of points. The logic is similar when there is a shot, we store the player, team, and the number of points, either, 1, 2, or 3. Finally, if the user enters stop, the program just stops.

The code below implements this possible solution

[ ]:
# We will use datetime to represent timestamps
import datetime

# This is our array of match statistics
stats_array = []

# Function to get the points of a player
def get_points(player, team):
  points = 0
  # Iterate on stats and if stat is of type Shot, then count the points
  for stat in stats_array:
    if stat["type"] == "shot" and stat["player"] == player and stat["team"] == team:
      points += stat["points"]

  print("Player {0} (team {1}) now has {2} points".format(player_number, teams[team], points))

  return points

# Function to get the faults of a player
def get_faults(player, team):
  faults = 0
  #Iterate on stats, and if stat is of type fault and the fault is made by a
  #player, then increase the number of faults
  for stat in stats_array:
    if stat["type"] == "fault" and stat["player"] == player and stat["team"] == team:
      faults += 1
  print("Player {0} (team {1}) now has {2} faults".format(player, teams[team], faults))
  return faults

# Here we start the script
# Name of the game to be stored in the statistic
game_name = input("Enter the name of the game: ")

# Name of the teams
team_1 = input("Enter the name of the first team: ")
team_2 = input("Enter the name of the second team: ")

teams = [team_1, team_2]
#Let´s ask the user for confirmation, we collect the current time and store in the
# stats array a dictionary with the type of stat as game_start and the current date
input("Press Enter to confirm game start")
game_start = datetime.datetime.now()
date_format = "%X"
stats_array.append({"type": "game_start", "timestamp": game_start.isoformat(), "teams": teams})
print("Now: ", game_start)


while True:
  #Get the stat type from the user
  stats_type = input("Enter statistic type (either shot or fault), or type stop to end the game: ")
  #If the user enter stop, then just break the while loop
  if stats_type == "stop":
    break
  else:
    # Get the time stamp of the statistic we want to store
    stat_date = datetime.datetime.now()

    # store the time stamp and the type of statistic
    stat = {"type": stats_type, "timestamp": stat_date.isoformat()}

    #if it is a shot, get the points and the player
    if stats_type == "shot":
      player_number = int(input("Enter the number of the player: "))
      team = int(input("Enter player's team (either 0 for {0} or 1 for {1}): ".format(team_1, team_2)))
      points = int(input("Enter points (either 0 for free shot, 1 for double, 3 for triple): "))
      if (points in [1, 2, 3]) and (team in [0, 1]):
        stat["player"]=player_number
        stat["points"]=points
        stat["team"]=team
        stats_array.append(stat)
        # Show a message with the total number of points
        get_points(player_number, team)
      else:
        print("problem with statistic, try again")
        continue
    elif stats_type == "fault":
        # if it´s a fault, get the player number and the team
        player1_number = int(input("Enter the number of the player that made the fault: "))
        team = int(input("Enter player's team (either 0 for {0} or 1 for {1}): ".format(team_1, team_2)))
        if (team in [0, 1]):
          #Get the number of the player that received the fault
          player2_number = int(input("Enter the number of the player that received the fault: "))
          stat["player"]=player1_number
          stat["team"]=team
          stat["received_by"]=player2_number
          stats_array.append(stat)
          #Show a message with the number of faults made by player
          get_faults(player1_number, team)
        else:
          print("problem with statistic, try again")
          continue
print(stats_array)
[ ]:
# We will use datetime to represent timestamps
import datetime

# This is our array of match statistics
stats_array = []

# Function to get the points of a player
def get_points(player, team):
  points = 0
  # Iterate on stats and if stat is of type Shot, then count the points
  for stat in stats_array:
    if stat["type"] == "shot" and stat["player"] == player and stat["team"] == team:
      points += stat["points"]

  print("Player {0} (team {1}) now has {2} points".format(player_number, teams[team], points))

  return points

# Function to get the faults of a player
def get_faults(player, team):
  faults = 0
  #Iterate on stats, and if stat is of type fault and the fault is made by a
  #player, then increase the number of faults
  for stat in stats_array:
    if stat["type"] == "fault" and stat["player"] == player and stat["team"] == team:
      faults += 1
  print("Player {0} (team {1}) now has {2} faults".format(player, teams[team], faults))
  return faults

# Here we start the script
# Name of the game to be stored in the statistic
game_name = input("Enter the name of the game: ")

# Name of the teams
team_1 = input("Enter the name of the first team: ")
team_2 = input("Enter the name of the second team: ")

teams = [team_1, team_2]
#Let´s ask the user for confirmation, we collect the current time and store in the
# stats array a dictionary with the type of stat as game_start and the current date
input("Press Enter to confirm game start")
game_start = datetime.datetime.now()
date_format = "%X"
stats_array.append({"type": "game_start", "timestamp": game_start.isoformat(), "teams": teams})
print("Now: ", game_start)


while True:
  #Get the stat type from the user
  stats_type = input("Enter statistic type (either shot or fault), or type stop to end the game: ")
  #If the user enter stop, then just break the while loop
  if stats_type == "stop":
    break
  else:
    # Get the time stamp of the statistic we want to store
    stat_date = datetime.datetime.now()

    # store the time stamp and the type of statistic
    stat = {"type": stats_type, "timestamp": stat_date.isoformat()}

    #if it is a shot, get the points and the player
    if stats_type == "shot":
      player_number = int(input("Enter the number of the player: "))
      team = int(input("Enter player's team (either 0 for {0} or 1 for {1}): ".format(team_1, team_2)))
      points = int(input("Enter points (either 0 for free shot, 1 for double, 3 for triple): "))
      if (points in [1, 2, 3]) and (team in [0, 1]):
        stat["player"]=player_number
        stat["points"]=points
        stat["team"]=team
        stats_array.append(stat)
        # Show a message with the total number of points
        get_points(player_number, team)
      else:
        print("problem with statistic, try again")
        continue
    elif stats_type == "fault":
        # if it´s a fault, get the player number and the team
        player1_number = int(input("Enter the number of the player that made the fault: "))
        team = int(input("Enter player's team (either 0 for {0} or 1 for {1}): ".format(team_1, team_2)))
        if (team in [0, 1]):
          #Get the number of the player that received the fault
          player2_number = int(input("Enter the number of the player that received the fault: "))
          stat["player"]=player1_number
          stat["team"]=team
          stat["received_by"]=player2_number
          stats_array.append(stat)
          #Show a message with the number of faults made by player
          get_faults(player1_number, team)
        else:
          print("problem with statistic, try again")
          continue
print(stats_array)
[1]:
# We will use datetime to represent timestamps
import datetime

# This is our array of match statistics
stats_array = []

# Function to get the points of a player
def get_points(player, team):
  points = 0
  # Iterate on stats and if stat is of type Shot, then count the points
  for stat in stats_array:
    if stat["type"] == "shot" and stat["player"] == player and stat["team"] == team:
      points += stat["points"]

  print("Player {0} (team {1}) now has {2} points".format(player_number, teams[team], points))

  return points

# Function to get the faults of a player
def get_faults(player, team):
  faults = 0
  #Iterate on stats, and if stat is of type fault and the fault is made by a
  #player, then increase the number of faults
  for stat in stats_array:
    if stat["type"] == "fault" and stat["player"] == player and stat["team"] == team:
      faults += 1
  print("Player {0} (team {1}) now has {2} faults".format(player, teams[team], faults))
  return faults

# Here we start the script
# Name of the game to be stored in the statistic
game_name = input("Enter the name of the game: ")

# Name of the teams
team_1 = input("Enter the name of the first team: ")
team_2 = input("Enter the name of the second team: ")

teams = [team_1, team_2]
#Let´s ask the user for confirmation, we collect the current time and store in the
# stats array a dictionary with the type of stat as game_start and the current date
input("Press Enter to confirm game start")
game_start = datetime.datetime.now()
date_format = "%X"
stats_array.append({"type": "game_start", "timestamp": game_start.isoformat(), "teams": teams})
print("Now: ", game_start)


while True:
  #Get the stat type from the user
  stats_type = input("Enter statistic type (either shot or fault), or type stop to end the game: ")
  #If the user enter stop, then just break the while loop
  if stats_type == "stop":
    break
  else:
    # Get the time stamp of the statistic we want to store
    stat_date = datetime.datetime.now()

    # store the time stamp and the type of statistic
    stat = {"type": stats_type, "timestamp": stat_date.isoformat()}

    #if it is a shot, get the points and the player
    if stats_type == "shot":
      player_number = int(input("Enter the number of the player: "))
      team = int(input("Enter player's team (either 0 for {0} or 1 for {1}): ".format(team_1, team_2)))
      points = int(input("Enter points (either 0 for free shot, 1 for double, 3 for triple): "))
      if (points in [1, 2, 3]) and (team in [0, 1]):
        stat["player"]=player_number
        stat["points"]=points
        stat["team"]=team
        stats_array.append(stat)
        # Show a message with the total number of points
        get_points(player_number, team)
      else:
        print("problem with statistic, try again")
        continue
    elif stats_type == "fault":
        # if it´s a fault, get the player number and the team
        player1_number = int(input("Enter the number of the player that made the fault: "))
        team = int(input("Enter player's team (either 0 for {0} or 1 for {1}): ".format(team_1, team_2)))
        if (team in [0, 1]):
          #Get the number of the player that received the fault
          player2_number = int(input("Enter the number of the player that received the fault: "))
          stat["player"]=player1_number
          stat["team"]=team
          stat["received_by"]=player2_number
          stats_array.append(stat)
          #Show a message with the number of faults made by player
          get_faults(player1_number, team)
        else:
          print("problem with statistic, try again")
          continue
print(stats_array)
Enter the name of the game: ACB game 12
Enter the name of the first team: Valencia Basket
Enter the name of the second team: Real Madrid
Press Enter to confirm game start
Now:  2022-01-05 11:42:03.792167
[{'type': 'game_start', 'timestamp': '2022-01-05T11:42:03.792167', 'teams': ['Valencia Basket', 'Real Madrid']}]
Enter statistic type (either shot or fault), or type stop to end the game: shot
Enter the number of the player: 7
Enter player's team (either 0 for Valencia Basket or 1 for Real Madrid): 0
Enter points (either 0 for free shot, 1 for double, 3 for triple): 3
Player 7 (team Valencia Basket) now has 3 points
Enter statistic type (either shot or fault), or type stop to end the game: fault
Enter the number of the player that made the fault: 6
Enter player's team (either 0 for Valencia Basket or 1 for Real Madrid): 1
Enter the number of the player that received the fault: 11
Player 6 (team Real Madrid) now has 1 faults
Enter statistic type (either shot or fault), or type stop to end the game: stop
[{'type': 'game_start', 'timestamp': '2022-01-05T11:42:03.792167', 'teams': ['Valencia Basket', 'Real Madrid']}, {'type': 'shot', 'timestamp': '2022-01-05T11:43:17.030771', 'player': 7, 'points': 3, 'team': 0}, {'type': 'fault', 'timestamp': '2022-01-05T11:43:45.966949', 'player': 6, 'team': 1, 'received_by': 11}]